﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace M.Web
{
	/// <summary>
	/// 用于Web后端或WinForm使用的HttpReqeust
	/// </summary>
	public static class AjaxHttpRequest
	{
		private const string DefaultUserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";

		#region 从响应中获取响应字符串
		/// <summary>
		/// 从响应中获取响应字符串
		/// </summary>
		/// <param name="response"></param>
		/// <returns></returns>
		public static string GetResponseString(HttpWebResponse response)
		{
			MValidator.CheckForNullReference("Response", response);
			try
			{
				using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
				{
					return reader.ReadToEnd();
				}
			}
			catch
			{
				throw;
			}
			finally
			{
				if (response != null)
					response.Close();
			}
		}
		#endregion

		#region HttpGet
		/// <summary>
		/// 通过GET方式请求Web页面并获取响应
		/// </summary>
		/// <param name="url">Web页面地址</param>
		/// <returns>请求返回的字符串</returns>
		public static string Get(string url)
		{
			return Get(url, null);
		}
		/// <summary>
		/// 通过GET方式请求Web页面并获取响应
		/// </summary>
		/// <param name="url">Web页面地址</param>
		/// <param name="cookies">随同HTTP请求发送的Cookie信息，如果不需要身份验证可以为空</param>
		/// <returns>请求返回的字符串</returns>
		public static string Get(string url, CookieCollection cookies)
		{
			return Get(url, null, null, cookies);
		}
		/// <summary>
		/// 通过GET方式请求Web页面并获取响应
		/// </summary>
		/// <param name="url">Web页面地址</param>
		/// <param name="timeout">页面超时时间（以毫秒为单位）</param>
		/// <param name="cookies">随同HTTP请求发送的Cookie信息，如果不需要身份验证可以为空</param>
		/// <returns>请求返回的字符串</returns>
		public static string Get(string url, int? timeout, CookieCollection cookies)
		{
			return Get(url, timeout, null, cookies);
		}
		/// <summary>
		/// 通过GET方式请求Web页面并获取响应
		/// </summary>
		/// <param name="url">Web页面地址</param>
		/// <param name="timeout">页面超时时间（以毫秒为单位）</param>
		/// <param name="userAgent">请求的客户端浏览器信息，可以为空</param>
		/// <param name="cookies">随同HTTP请求发送的Cookie信息，如果不需要身份验证可以为空</param>
		/// <returns>请求返回的字符串</returns>
		public static string Get(string url, int? timeout, string userAgent, CookieCollection cookies)
		{
			MValidator.CheckForEmptyString("Url", url);

			HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
			request.Method = "GET";
			request.UserAgent = string.IsNullOrEmpty(userAgent) ? DefaultUserAgent : userAgent;
			request.UseDefaultCredentials = true;
			if (timeout.HasValue) request.Timeout = timeout.Value;
			if (cookies != null && cookies.Count > 0)
			{
				request.CookieContainer = new CookieContainer();
				request.CookieContainer.Add(cookies);
			}

			return GetResponseString(request.GetResponse() as HttpWebResponse);
		}
		#endregion

		#region HttpPost
		/// <summary>
		/// 通过POST方式请求Web页面并获取响应
		/// </summary>
		/// <param name="url"></param>
		/// <returns></returns>
		public static string Post(string url)
		{
			Dictionary<string, string> parameters = new Dictionary<string, string>();
			parameters.Add("nothing", "nothing");
			return Post(url, parameters);
		}
		/// <summary>
		/// 通过POST方式请求Web页面并获取响应
		/// </summary>
		/// <param name="url"></param>
		/// <param name="parameters"></param>
		/// <returns></returns>
		public static string Post(string url, IDictionary<string, string> parameters)
		{
			return Post(url, parameters, null);
		}
		/// <summary>
		/// 通过POST方式请求Web页面并获取响应
		/// </summary>
		/// <param name="url">Web页面地址</param>
		/// <param name="parameters">随同请求POST的参数名称及参数值字典</param>
		/// <param name="cookies">随同HTTP请求发送的Cookie信息，如果不需要身份验证可以为空</param>
		/// <returns></returns>
		public static string Post(string url, IDictionary<string, string> parameters, CookieCollection cookies)
		{
			return Post(url, parameters, Encoding.UTF8, cookies);
		}
		/// <summary>
		/// 通过POST方式请求Web页面并获取响应
		/// </summary>
		/// <param name="url">Web页面地址</param>
		/// <param name="parameters">随同请求POST的参数名称及参数值字典</param>
		/// <param name="requestEncoding">发送HTTP请求时所用的编码</param>
		/// <param name="cookies">随同HTTP请求发送的Cookie信息，如果不需要身份验证可以为空</param>
		/// <returns></returns>
		public static string Post(string url, IDictionary<string, string> parameters, Encoding requestEncoding, CookieCollection cookies)
		{
			return Post(url, parameters, null, requestEncoding, cookies);
		}
		/// <summary>
		/// 通过POST方式请求Web页面并获取响应
		/// </summary>
		/// <param name="url">Web页面地址</param>
		/// <param name="parameters">随同请求POST的参数名称及参数值字典</param>
		/// <param name="timeout">页面超时时间（以毫秒为单位）</param>
		/// <param name="requestEncoding">发送HTTP请求时所用的编码</param>
		/// <param name="cookies">随同HTTP请求发送的Cookie信息，如果不需要身份验证可以为空</param>
		/// <returns></returns>
		public static string Post(string url, IDictionary<string, string> parameters, int? timeout, Encoding requestEncoding, CookieCollection cookies)
		{
			return Post(url, parameters, timeout, null, requestEncoding, cookies);
		}
		/// <summary>
		/// 通过POST方式请求Web页面并获取响应
		/// </summary>
		/// <param name="url">Web页面地址</param>
		/// <param name="parameters">随同请求POST的参数名称及参数值字典</param>
		/// <param name="timeout">页面超时时间（以毫秒为单位）</param>
		/// <param name="userAgent">请求的客户端浏览器信息，可以为空</param>
		/// <param name="requestEncoding">发送HTTP请求时所用的编码</param>
		/// <param name="cookies">随同HTTP请求发送的Cookie信息，如果不需要身份验证可以为空</param>
		/// <returns>请求返回的字符串</returns>
		public static string Post(string url, IDictionary<string, string> parameters, int? timeout, string userAgent, Encoding requestEncoding, CookieCollection cookies)
		{
			MValidator.CheckForEmptyString("Url", url);
			MValidator.CheckForNullReference("Post Parameters", parameters);
			MValidator.CheckValueMinLimit<int>("Post Parameters Count", parameters.Count, 1);
			MValidator.CheckForNullReference("Request Encoding", requestEncoding);
			// 设置Https相关参数
			HttpWebRequest request = null;
			//如果是发送HTTPS请求  
			if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
			{
				ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
				request = WebRequest.Create(url) as HttpWebRequest;
				request.ProtocolVersion = HttpVersion.Version10;
			}
			else
			{
				request = WebRequest.Create(url) as HttpWebRequest;
			}
			request.Method = "POST";
			request.ContentType = "application/x-www-form-urlencoded";
			//request.UseDefaultCredentials = true;
			//CredentialCache cc = new CredentialCache();
			//cc.Add(new Uri("http://www.mysoft.net.cn/"), "Digest", new NetworkCredential("duh", "Mysoft1984416", "mysoft"));
			//request.Credentials = cc;
			//request.AllowAutoRedirect = true;
			//request.MaximumAutomaticRedirections = 10;

			request.UserAgent = string.IsNullOrEmpty(userAgent) ? DefaultUserAgent : userAgent;
			if (timeout.HasValue) request.Timeout = timeout.Value;
			if (cookies != null && cookies.Count > 0)
			{
				request.CookieContainer = new CookieContainer();
				request.CookieContainer.Add(cookies);
			}

			//如果需要POST数据  

			StringBuilder buffer = new StringBuilder();
			int i = 0;
			foreach (string key in parameters.Keys)
			{
				if (i > 0)
				{
					buffer.AppendFormat("&{0}={1}", key, parameters[key]);
				}
				else
				{
					buffer.AppendFormat("{0}={1}", key, parameters[key]);
				}
				i++;
			}
			byte[] data = requestEncoding.GetBytes(buffer.ToString());
			using (Stream stream = request.GetRequestStream())
			{
				stream.Write(data, 0, data.Length);
			}

			return GetResponseString(request.GetResponse() as HttpWebResponse);
		}

		private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
		{
			return true; //总是接受  
		}

		#endregion
	}
}
